package com.zhx.ad.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhx.ad.common.exception.AdException;
import com.zhx.ad.constants.Constants;
import com.zhx.ad.entity.AdPlan;
import com.zhx.ad.entity.AdUnit;
import com.zhx.ad.entity.unitcondition.AdUnitIt;
import com.zhx.ad.entity.unitcondition.AdUnitKeyword;
import com.zhx.ad.entity.unitcondition.AdUnitdistrict;
import com.zhx.ad.entity.unitcondition.CreativeUnit;
import com.zhx.ad.mapper.AdUnitMapper;
import com.zhx.ad.service.*;
import com.zhx.ad.client.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 *describe: 
 *
 *@author zhanghaixuan
 *@date 2019/02/02
 **/
@Service
public class AdUnitServiceImpl extends ServiceImpl<AdUnitMapper, AdUnit> implements IAdUnitService {
	
	
	@Autowired
	private IAdPlanService adPlanService;

	@Autowired
	private IAdUnitKeywordService unitKeywordRepository;

	@Autowired
	private IAdUnitDistrictservice unitDistrictRepository;

	@Autowired
	private IAdCreativeService creativeRepository;

	@Autowired
	private ICreativeUnitService unitItRepository;

	@Override
	public AdUnitResponse createUnit(AdUnitRequest request)
			throws AdException {

		if (!request.createValidate()) {
			throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
		}

		AdPlan adPlan = adPlanService.getById(request.getPlanId());
		if (adPlan == null ) {
			throw new AdException(Constants.ErrorMsg.CAN_NOT_FIND_RECORD);
		}

		AdUnit oldAdUnit = baseMapper.findByPlanIdAndUnitName(
				request.getPlanId(), request.getUnitName()
		);
		if (oldAdUnit != null) {
			throw new AdException(Constants.ErrorMsg.SAME_NAME_UNIT_ERROR);
		}
		AdUnit newAdUnit =  new AdUnit(request.getPlanId(), request.getUnitName(),
				request.getPositionType(), request.getBudget());


		baseMapper.insert(newAdUnit);

		return new AdUnitResponse(newAdUnit.getId(),
				newAdUnit.getUnitName());
	}

	@Override
	public AdUnitKeywordResponse createUnitKeyword(
			AdUnitKeywordRequest request) throws AdException {

		List<String> unitIds = request.getUnitKeywords().stream()
				.map(AdUnitKeywordRequest.UnitKeyword::getUnitId)
				.collect(Collectors.toList());
		if (!isRelatedUnitExist(unitIds)) {
			throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
		}

		List<String> ids = Collections.emptyList();

		List<AdUnitKeyword> unitKeywords = new ArrayList<>();
		if (!CollectionUtils.isEmpty(request.getUnitKeywords())) {

			request.getUnitKeywords().forEach(i -> unitKeywords.add(
					new AdUnitKeyword(i.getUnitId(), i.getKeyword())
			));
			unitKeywordRepository.saveBatch(unitKeywords);

			ids = unitKeywords.stream().map(e->{
				return e.getId();
			}).collect(Collectors.toList());
		}

		return new AdUnitKeywordResponse(ids);
	}

	@Override
	public AdUnitItResponse createUnitIt(
			AdUnitItRequest request) throws AdException {

		List<String> unitIds = request.getUnitIts().stream()
				.map(AdUnitItRequest.UnitIt::getUnitId)
				.collect(Collectors.toList());
		if (!isRelatedUnitExist(unitIds)) {
			throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
		}

		List<AdUnitIt> unitIts = new ArrayList<>();
		request.getUnitIts().forEach(i -> unitIts.add(
				new AdUnitIt(i.getUnitId(), i.getItTag())
		));

		List<String> ids = listByIds(unitIts).stream()
				.map(AdUnit::getId)
				.collect(Collectors.toList());

		return new AdUnitItResponse(ids);
	}

	@Override
	public AdUnitDistrictResponse createUnitDistrict(
			AdUnitDistrictRequest request) throws AdException {

		List<String> unitIds = request.getUnitDistricts().stream()
				.map(AdUnitDistrictRequest.UnitDistrict::getUnitId)
				.collect(Collectors.toList());
		if (!isRelatedUnitExist(unitIds)) {
			throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
		}

		List<AdUnitdistrict> unitDistricts = new ArrayList<>();
		request.getUnitDistricts().forEach(d -> unitDistricts.add(
				new AdUnitdistrict(d.getUnitId(), d.getProvince(),
						d.getCity())
		));
		unitDistrictRepository.saveBatch(unitDistricts);;

		List<String> ids = unitDistricts.stream().map(AdUnitdistrict::getId).collect(Collectors.toList());

		return new AdUnitDistrictResponse(ids);
	}

	@Override
	public CreativeUnitResponse createCreativeUnit(
			CreativeUnitRequest request) throws AdException {

		List<String> unitIds = request.getUnitItems().stream()
				.map(CreativeUnitRequest.CreativeUnitItem::getUnitId)
				.collect(Collectors.toList());
		List<String> creativeIds = request.getUnitItems().stream()
				.map(CreativeUnitRequest.CreativeUnitItem::getCreativeId)
				.collect(Collectors.toList());

		if (!(isRelatedUnitExist(unitIds) && isRelatedUnitExist(creativeIds))) {
			throw new AdException(Constants.ErrorMsg.REQUEST_PARAM_ERROR);
		}

		List<CreativeUnit> creativeUnits = new ArrayList<>();
		request.getUnitItems().forEach(i -> creativeUnits.add(
				new CreativeUnit(i.getCreativeId(), i.getUnitId())
		));

		List<String> ids = creativeUnits.stream().map(e->{
			return e.getId();
		}).collect(Collectors.toList());

		return new CreativeUnitResponse(ids);
	}

	private boolean isRelatedUnitExist(List<String> unitIds) {

		if (CollectionUtils.isEmpty(unitIds)) {
			return false;
		}

		return baseMapper.selectBatchIds(unitIds).size() ==
				new HashSet<>(unitIds).size();
	}

	private boolean isRelatedCreativeExist(List<String> creativeIds) {

		if (CollectionUtils.isEmpty(creativeIds)) {
			return false;
		}

		return creativeRepository.listByIds(creativeIds).size() ==
				new HashSet<>(creativeIds).size();
	}
}
